package com.kadron.account;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.imageio.ImageIO;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.transaction.Transaction;
import org.jboss.seam.transaction.UserTransaction;
import org.richfaces.event.FileUploadListener;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

import com.kadron.common.KConst;
import com.kadron.common.KIDGenerator;
import com.kadron.common.KInitParams;
import com.kadron.common.KUtil;
import com.kadron.dao.KUserImageDAO;
import com.kadron.entity.User;
import com.kadron.entity.UserImage;
import com.kadron.exceptions.UploadImageException;
import com.kadron.img.ImageHelper;
import com.kadron.manager.KMessageManager;
import com.kadron.session.KUser;

@AutoCreate
@Name("kMyAvatar")
@Scope(ScopeType.PAGE)
public class KMyAvatar extends KMessageManager implements Serializable,FileUploadListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5307825474425830753L;

	private static final Log log = LogFactory.getLog(KMyAvatar.class);

	private User user;
	private UserImage img;
	
	@In
	private KUserImageDAO userImageDAO;

	@Create
	public void init() {
		user = KUser.instance().getUser();
		if (user == null) {
			setError(true);
		}
		img = userImageDAO.findByUser(user.getId());
	}

	public void save() {
		Map<String, String> params = FacesContext.getCurrentInstance()
				.getExternalContext().getRequestParameterMap();
		String x = params.get("x");
		String y = params.get("y");
		String w = params.get("w");
		String h = params.get("h");
		if (KUtil.isEmpty(x) 
				|| KUtil.isEmpty(y)
				|| KUtil.isEmpty(w)
				|| KUtil.isEmpty(h)) {
			bad("empty_selection");
			return;
		}
		
		int xPosition = Integer.parseInt(x);
		int yPosition = Integer.parseInt(y);
		int width = Integer.parseInt(w);
		int height = Integer.parseInt(h);
		if (width <= 0 || height <= 0) {
			bad("bad_selection_for_crop");
			return;			
		}
		
		String strDirectory = KInitParams.WEBAPPS_PATH + KInitParams.IMG_PATH + "/av_" + user.getId();
		
		//First delete old thumb image
		File thumb = new File(strDirectory+"/"+img.getThumb());
		if (thumb.exists()) {
			boolean deleted = thumb.delete();
			if (!deleted && log.isInfoEnabled()) {
				log.info("-------------- Avatar thumb not deleted ---------------");
			}
		}
		
		String uuid = "av_"+KIDGenerator.createUUID();
//		String imgPath = KInitParams.IMG_PATH + "/av_" + user.getId() + "/";
		BufferedImage originalImage = null;
		String imgName = img.getName();
		try {
			int IndexOf = imgName.lastIndexOf(".");
			String domainName = imgName.substring(IndexOf);
			String finalimage = uuid + domainName;
			if (log.isDebugEnabled()) {
				log.debug("Final Image===" + finalimage);
			}
			originalImage = ImageIO.read(new File(strDirectory+"/"+img.getName()));
			BufferedImage croped = ImageHelper.cropImage(originalImage, xPosition, yPosition, width, height);
			ImageIO.write(croped, "png", new File(strDirectory + "/" + finalimage));
			img.setThumb(finalimage);
			img = (UserImage) userImageDAO.update(img);
			good();
			init();
		} catch (Exception e) {
			e.printStackTrace();
			bad(KConst.BAD_THING);
		}
	}
	
	public boolean uploadVisible() {
		return img == null;
	}
	
	@Override
	public void processUpload(UploadEvent arg0) {
		UploadItem uploadItem = arg0.getUploadItem();
		if (uploadItem == null) {
			bad(KConst.BAD_THING);
			return;
		}
		int size = uploadItem.getFileSize();
		if (size > 1024000) {
			bad(KConst.BAD_THING);
			return;
		}
		String itemName = uploadItem.getFileName();
		byte[] data = new byte[4096];
		FileOutputStream outputStream = null;
		FileInputStream inputStream = null;
		String strDirectory = "";
		String imgPath = "";
		UserTransaction transaction = null;
		try {
			transaction = Transaction.instance();
			strDirectory = KInitParams.WEBAPPS_PATH + KInitParams.IMG_PATH+"/av_"+user.getId();
			imgPath = KInitParams.IMG_PATH + "/av_"+user.getId()+"/";
			File directory = new File(strDirectory);
			if (!directory.exists()) {
				directory.mkdir();
			}

			String uuid = KIDGenerator.createUUID();
			UserImage userImage = new UserImage(user.getId());
			userImage.setPath(imgPath);
			int IndexOf = itemName.lastIndexOf(".");
			String domainName = itemName.substring(IndexOf);
			if (log.isDebugEnabled()) {
				log.debug("domainName: " + domainName);
			}
			if (KUtil.isEmpty(domainName)) {
				throw new UploadImageException("Domain name je prazno");
			} else if (!domainName.equalsIgnoreCase(".png")
					&& !domainName.equalsIgnoreCase(".jpg")
					&& !domainName.equalsIgnoreCase(".JPEG")) {
				throw new UploadImageException("Domain Name not acceptable");
			}
			String finalimage = uuid + domainName;
			if (log.isDebugEnabled()) {
				log.debug("Final Image===" + finalimage);
			}
			userImage.setName(finalimage); 
			userImage = (UserImage) userImageDAO.update(userImage);

			File file = new File(strDirectory + "/" + finalimage);
			outputStream = new FileOutputStream(file, true);
			inputStream = new FileInputStream(uploadItem.getFile());
			if (!file.exists()) {
				file.createNewFile();
			}
			int bit;
			while ((bit = inputStream.read(data)) != -1) {
				outputStream.write(data, 0, bit);
			}
			inputStream.close();
			outputStream.flush();
			outputStream.close();
			transaction.commit();
//			init();
			good();
		} catch (Exception e) {
			e.printStackTrace();
			try {
				if (transaction != null) {
					transaction.rollback();
				}
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			bad(KConst.BAD_THING);
		} finally {
			try {
				inputStream.close();
				outputStream.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}
	
	public void deleteImg(UserImage img) {
		if (img == null) {
			bad(KConst.BAD_THING);
			return;
		}
		UserTransaction transaction = null;
		try {
			transaction = Transaction.instance();
			img = userImageDAO.find(img.getId(), UserImage.class);
			String strDirectory = KInitParams.WEBAPPS_PATH + KInitParams.IMG_PATH + "/av_" + user.getId();
			File file = new File(strDirectory+"/"+img.getName());
			File thumb = new File(strDirectory+"/"+img.getThumb());
			if (file.exists()) {
				boolean deleted = file.delete();
				if (!deleted) {
					if (log.isErrorEnabled()) {						
						log.error("Not deleted File: "+strDirectory+"/"+img.getName());
					}
					bad("Not deleted File: "+strDirectory+"/"+img.getName());
					return;
				}
			}
			if (thumb.exists()) {
				boolean deleted = thumb.delete();
				if (!deleted) {
					if (log.isErrorEnabled()) {						
						log.error("Not deleted THUMB File: "+strDirectory+"/"+img.getThumb());
					}
					bad("Not deleted THUMB File: "+strDirectory+"/"+img.getThumb());
					return;
				}
			}
			userImageDAO.delete(img);
			transaction.commit();
			init();
			good();			
		} catch (Exception e) {
			e.printStackTrace();
			if (transaction!=null) {
				try {
					transaction.rollback();					
				} catch (Exception e2) {
					log.error(e2);
				}
			}
			bad(KConst.BAD_THING);
		}
	}

	public User getUser() {
		return user;
	}

	public UserImage getImg() {
		return img;
	}
	
}